#include "permissionmanager.h"
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>
#include <QDateTime>
#include <QSqlDatabase>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QFile>
#include <QStandardPaths>

PermissionManager::PermissionManager(QObject *parent)
    : QObject(parent),
      m_userSession(nullptr)
{
    m_configFilePath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/permissions.json";
    setupDefaultPermissions();
    setupDefaultGroups();
}

PermissionManager::~PermissionManager()
{
}

bool PermissionManager::initialize(UserSession* userSession)
{
    m_userSession = userSession;
    
    if (m_userSession) {
        connect(m_userSession, &UserSession::currentUserChanged, 
                this, &PermissionManager::onUserChanged);
        connect(m_userSession, &UserSession::userDeleted, 
                this, &PermissionManager::onUserDeleted);
    }
    
    return loadPermissionConfig();
}

bool PermissionManager::hasPermission(const QString& username, Permission permission) const
{
    if (!isValidPermission(permission)) {
        return false;
    }
    
    QSet<Permission> userPermissions = combinePermissions(username);
    return userPermissions.contains(permission);
}

bool PermissionManager::hasPermission(const QString& username, const QString& permissionStr) const
{
    Permission permission = stringToPermission(permissionStr);
    return hasPermission(username, permission);
}

bool PermissionManager::hasAnyPermission(const QString& username, const QList<Permission>& permissions) const
{
    QSet<Permission> userPermissions = combinePermissions(username);
    
    for (Permission permission : permissions) {
        if (userPermissions.contains(permission)) {
            return true;
        }
    }
    
    return false;
}

bool PermissionManager::hasAllPermissions(const QString& username, const QList<Permission>& permissions) const
{
    QSet<Permission> userPermissions = combinePermissions(username);
    
    for (Permission permission : permissions) {
        if (!userPermissions.contains(permission)) {
            return false;
        }
    }
    
    return true;
}

QSet<Permission> PermissionManager::getRolePermissions(UserRole role) const
{
    return m_rolePermissions.value(role, QSet<Permission>());
}

bool PermissionManager::setRolePermissions(UserRole role, const QSet<Permission>& permissions)
{
    m_rolePermissions[role] = permissions;
    emit rolePermissionsChanged(role);
    return savePermissionConfig();
}

QSet<Permission> PermissionManager::getUserPermissions(const QString& username) const
{
    return m_userPermissions.value(username, QSet<Permission>());
}

bool PermissionManager::setUserPermissions(const QString& username, const QSet<Permission>& permissions)
{
    m_userPermissions[username] = permissions;
    emit permissionsChanged(username);
    return savePermissionConfig();
}

bool PermissionManager::addUserPermission(const QString& username, Permission permission)
{
    if (!isValidPermission(permission)) {
        return false;
    }
    
    if (!m_userPermissions.contains(username)) {
        m_userPermissions[username] = QSet<Permission>();
    }
    
    m_userPermissions[username].insert(permission);
    emit permissionsChanged(username);
    return savePermissionConfig();
}

bool PermissionManager::removeUserPermission(const QString& username, Permission permission)
{
    if (!m_userPermissions.contains(username)) {
        return true; // Already removed
    }
    
    m_userPermissions[username].remove(permission);
    emit permissionsChanged(username);
    return savePermissionConfig();
}

bool PermissionManager::clearUserPermissions(const QString& username)
{
    if (m_userPermissions.contains(username)) {
        m_userPermissions.remove(username);
        emit permissionsChanged(username);
        return savePermissionConfig();
    }
    
    return true;
}

QList<PermissionGroup> PermissionManager::getPermissionGroups() const
{
    return m_permissionGroups;
}

bool PermissionManager::createPermissionGroup(const QString& groupName, const QString& description, 
                                            const QSet<Permission>& permissions)
{
    // Check if group already exists
    for (const PermissionGroup& group : m_permissionGroups) {
        if (group.groupName == groupName) {
            return false; // Group already exists
        }
    }
    
    PermissionGroup newGroup;
    newGroup.groupName = groupName;
    newGroup.description = description;
    newGroup.permissions = permissions;
    
    m_permissionGroups.append(newGroup);
    emit permissionGroupCreated(groupName);
    return savePermissionConfig();
}

bool PermissionManager::deletePermissionGroup(const QString& groupName)
{
    for (int i = 0; i < m_permissionGroups.size(); ++i) {
        if (m_permissionGroups[i].groupName == groupName) {
            m_permissionGroups.removeAt(i);
            
            // Remove group from all users
            for (auto it = m_userGroups.begin(); it != m_userGroups.end(); ++it) {
                it.value().remove(groupName);
            }
            
            emit permissionGroupDeleted(groupName);
            return savePermissionConfig();
        }
    }
    
    return false; // Group not found
}

bool PermissionManager::assignGroupToUser(const QString& username, const QString& groupName)
{
    // Check if group exists
    bool groupExists = false;
    for (const PermissionGroup& group : m_permissionGroups) {
        if (group.groupName == groupName) {
            groupExists = true;
            break;
        }
    }
    
    if (!groupExists) {
        return false;
    }
    
    if (!m_userGroups.contains(username)) {
        m_userGroups[username] = QSet<QString>();
    }
    
    m_userGroups[username].insert(groupName);
    emit permissionsChanged(username);
    return savePermissionConfig();
}

bool PermissionManager::removeGroupFromUser(const QString& username, const QString& groupName)
{
    if (!m_userGroups.contains(username)) {
        return true; // Already removed
    }
    
    m_userGroups[username].remove(groupName);
    emit permissionsChanged(username);
    return savePermissionConfig();
}

QString PermissionManager::permissionToString(Permission permission) const
{
    switch (permission) {
        case PERM_DEVICE_CONTROL: return "device.control";
        case PERM_SAMPLING_MANAGE: return "sampling.manage";
        case PERM_USER_MANAGE: return "user.manage";
        case PERM_DATA_VIEW: return "data.view";
        case PERM_DATA_EXPORT: return "data.export";
        case PERM_SYSTEM_CONFIG: return "system.config";
        case PERM_AUDIT_VIEW: return "audit.view";
        case PERM_BACKUP_RESTORE: return "backup.restore";
        case PERM_MAINTENANCE: return "maintenance";
        default: return "unknown";
    }
}

Permission PermissionManager::stringToPermission(const QString& permissionStr) const
{
    if (permissionStr == "device.control") return PERM_DEVICE_CONTROL;
    if (permissionStr == "sampling.manage") return PERM_SAMPLING_MANAGE;
    if (permissionStr == "user.manage") return PERM_USER_MANAGE;
    if (permissionStr == "data.view") return PERM_DATA_VIEW;
    if (permissionStr == "data.export") return PERM_DATA_EXPORT;
    if (permissionStr == "system.config") return PERM_SYSTEM_CONFIG;
    if (permissionStr == "audit.view") return PERM_AUDIT_VIEW;
    if (permissionStr == "backup.restore") return PERM_BACKUP_RESTORE;
    if (permissionStr == "maintenance") return PERM_MAINTENANCE;
    
    return PERM_DATA_VIEW; // Default
}

QStringList PermissionManager::getAllPermissionStrings() const
{
    QStringList permissions;
    permissions << "device.control" << "sampling.manage" << "user.manage"
                << "data.view" << "data.export" << "system.config"
                << "audit.view" << "backup.restore" << "maintenance";
    return permissions;
}

QString PermissionManager::getPermissionDescription(Permission permission) const
{
    switch (permission) {
        case PERM_DEVICE_CONTROL: return "设备控制权限";
        case PERM_SAMPLING_MANAGE: return "采样管理权限";
        case PERM_USER_MANAGE: return "用户管理权限";
        case PERM_DATA_VIEW: return "数据查看权限";
        case PERM_DATA_EXPORT: return "数据导出权限";
        case PERM_SYSTEM_CONFIG: return "系统配置权限";
        case PERM_AUDIT_VIEW: return "审计日志查看权限";
        case PERM_BACKUP_RESTORE: return "备份恢复权限";
        case PERM_MAINTENANCE: return "系统维护权限";
        default: return "未知权限";
    }
}

bool PermissionManager::currentUserHasPermission(Permission permission) const
{
    if (!m_userSession || !m_userSession->isLoggedIn()) {
        return false;
    }
    
    return hasPermission(m_userSession->getCurrentUser(), permission);
}

bool PermissionManager::currentUserHasPermission(const QString& permissionStr) const
{
    if (!m_userSession || !m_userSession->isLoggedIn()) {
        return false;
    }
    
    return hasPermission(m_userSession->getCurrentUser(), permissionStr);
}

QSet<Permission> PermissionManager::getCurrentUserPermissions() const
{
    if (!m_userSession || !m_userSession->isLoggedIn()) {
        return QSet<Permission>();
    }
    
    return combinePermissions(m_userSession->getCurrentUser());
}

bool PermissionManager::loadPermissionConfig()
{
    QFile file(m_configFilePath);
    if (!file.open(QIODevice::ReadOnly)) {
        qDebug() << "权限配置文件不存在，使用默认配置";
        return true; // Use defaults
    }
    
    QByteArray data = file.readAll();
    QJsonDocument doc = QJsonDocument::fromJson(data);
    
    if (!doc.isObject()) {
        qWarning() << "权限配置文件格式错误";
        return false;
    }
    
    QJsonObject root = doc.object();
    
    // Load role permissions
    if (root.contains("rolePermissions")) {
        QJsonObject rolePerms = root["rolePermissions"].toObject();
        for (auto it = rolePerms.begin(); it != rolePerms.end(); ++it) {
            UserRole role = static_cast<UserRole>(it.key().toInt());
            QJsonArray permArray = it.value().toArray();
            QSet<Permission> permissions;
            
            for (const QJsonValue& value : permArray) {
                permissions.insert(static_cast<Permission>(value.toInt()));
            }
            
            m_rolePermissions[role] = permissions;
        }
    }
    
    // Load user permissions
    if (root.contains("userPermissions")) {
        QJsonObject userPerms = root["userPermissions"].toObject();
        for (auto it = userPerms.begin(); it != userPerms.end(); ++it) {
            QString username = it.key();
            QJsonArray permArray = it.value().toArray();
            QSet<Permission> permissions;
            
            for (const QJsonValue& value : permArray) {
                permissions.insert(static_cast<Permission>(value.toInt()));
            }
            
            m_userPermissions[username] = permissions;
        }
    }
    
    return true;
}

bool PermissionManager::savePermissionConfig()
{
    QJsonObject root;
    
    // Save role permissions
    QJsonObject rolePerms;
    for (auto it = m_rolePermissions.begin(); it != m_rolePermissions.end(); ++it) {
        QJsonArray permArray;
        for (Permission perm : it.value()) {
            permArray.append(static_cast<int>(perm));
        }
        rolePerms[QString::number(static_cast<int>(it.key()))] = permArray;
    }
    root["rolePermissions"] = rolePerms;
    
    // Save user permissions
    QJsonObject userPerms;
    for (auto it = m_userPermissions.begin(); it != m_userPermissions.end(); ++it) {
        QJsonArray permArray;
        for (Permission perm : it.value()) {
            permArray.append(static_cast<int>(perm));
        }
        userPerms[it.key()] = permArray;
    }
    root["userPermissions"] = userPerms;
    
    QJsonDocument doc(root);
    
    QFile file(m_configFilePath);
    if (!file.open(QIODevice::WriteOnly)) {
        qWarning() << "无法保存权限配置文件:" << m_configFilePath;
        return false;
    }
    
    file.write(doc.toJson());
    return true;
}

void PermissionManager::resetToDefaultPermissions()
{
    m_rolePermissions.clear();
    m_userPermissions.clear();
    m_userGroups.clear();
    m_permissionGroups.clear();
    
    setupDefaultPermissions();
    setupDefaultGroups();
    savePermissionConfig();
}

void PermissionManager::onUserChanged(const QString& username)
{
    Q_UNUSED(username)
    // Handle user change if needed
}

void PermissionManager::onUserDeleted(const QString& username)
{
    // Clean up permissions for deleted user
    if (m_userPermissions.contains(username)) {
        m_userPermissions.remove(username);
        savePermissionConfig();
    }
    
    if (m_userGroups.contains(username)) {
        m_userGroups.remove(username);
        savePermissionConfig();
    }
}

void PermissionManager::setupDefaultPermissions()
{
    // Admin role - full permissions
    QSet<Permission> adminPerms;
    adminPerms << PERM_DEVICE_CONTROL << PERM_SAMPLING_MANAGE << PERM_USER_MANAGE
               << PERM_DATA_VIEW << PERM_DATA_EXPORT << PERM_SYSTEM_CONFIG
               << PERM_AUDIT_VIEW << PERM_BACKUP_RESTORE << PERM_MAINTENANCE;
    m_rolePermissions[USER_ROLE_ADMIN] = adminPerms;
    
    // Operator role - operational permissions
    QSet<Permission> operatorPerms;
    operatorPerms << PERM_DEVICE_CONTROL << PERM_SAMPLING_MANAGE
                  << PERM_DATA_VIEW << PERM_DATA_EXPORT << PERM_AUDIT_VIEW;
    m_rolePermissions[USER_ROLE_OPERATOR] = operatorPerms;
    
    // Viewer role - read-only permissions
    QSet<Permission> viewerPerms;
    viewerPerms << PERM_DATA_VIEW << PERM_AUDIT_VIEW;
    m_rolePermissions[USER_ROLE_VIEWER] = viewerPerms;
}

void PermissionManager::setupDefaultGroups()
{
    // Create default permission groups
    QSet<Permission> deviceGroup;
    deviceGroup << PERM_DEVICE_CONTROL << PERM_SAMPLING_MANAGE;
    createPermissionGroup("设备操作", "设备控制和采样管理权限", deviceGroup);
    
    QSet<Permission> dataGroup;
    dataGroup << PERM_DATA_VIEW << PERM_DATA_EXPORT;
    createPermissionGroup("数据管理", "数据查看和导出权限", dataGroup);
    
    QSet<Permission> systemGroup;
    systemGroup << PERM_SYSTEM_CONFIG << PERM_BACKUP_RESTORE << PERM_MAINTENANCE;
    createPermissionGroup("系统管理", "系统配置和维护权限", systemGroup);
}

QSet<Permission> PermissionManager::combinePermissions(const QString& username) const
{
    QSet<Permission> allPermissions;
    
    // Get role-based permissions
    if (m_userSession) {
        UserInfo userInfo = m_userSession->getCurrentUserInfo();
        if (userInfo.username == username) {
            allPermissions.unite(getRolePermissions(userInfo.role));
        }
    }
    
    // Add user-specific permissions
    if (m_userPermissions.contains(username)) {
        allPermissions.unite(m_userPermissions[username]);
    }
    
    // Add group permissions
    if (m_userGroups.contains(username)) {
        const QSet<QString>& userGroups = m_userGroups[username];
        for (const QString& groupName : userGroups) {
            for (const PermissionGroup& group : m_permissionGroups) {
                if (group.groupName == groupName) {
                    allPermissions.unite(group.permissions);
                    break;
                }
            }
        }
    }
    
    return allPermissions;
}

bool PermissionManager::isValidPermission(Permission permission) const
{
    return permission >= PERM_DEVICE_CONTROL && permission <= PERM_MAINTENANCE;
}